//
//  SpeedCoachMemoryBlock.m
//  SpeedCoach Importer
//
//  Created by Roelant Ossewaarde on 4/11/11.
//  Copyright 2011 SUNY Buffalo. All rights reserved.
//

#import "SpeedCoachMemoryBlock.h"


@implementation SpeedCoachMemoryBlock

@synthesize automem;
@synthesize workoutmem;

-(id) initWithData:(NSData *) someData {
	if (self == [super init]) {
	//	automem = [[NSMutableArray alloc] initWithCapacity:1500];
	//	workoutmem = [[NSMutableArray alloc] initWithCapacity:510];
		if ([SpeedCoachMemoryBlock isValidEprom1:someData]) {
			data = [[NSData alloc] initWithData:someData];
			
			return self;;
		}
	}
	return nil;
}

-(void) dealloc {
//	[automem release];
//	[workoutmem release];
	[super dealloc];
}

-(NSArray *) parseWorkoutMemoryBlock:(BOOL)automem_area {
	int relative_sequenceno = 0;
	int sequenceno = 0;
	int i = 0;
	int i_threshold;
	int cumulativeDistance = 0;
	if (automem_area == YES) i_threshold = 1500; else i_threshold = 510;
	
	NSMutableArray *destinationArray = [[[NSMutableArray alloc] initWithCapacity:1500] autorelease];;
	NSDate *date = nil;
	ChunkType lastChunkType;
	do {
		NSData *datablock;
		if (automem_area == YES) {
			datablock = (NSData *)[self automemChunkByNum:i];
		} else {
			datablock = (NSData *)[self workoutmemChunkByNum:i];
		}
		NSLog(@"chunk %i", i);
		Chunk *chunk = [[Chunk alloc ] initWithData:datablock];
		[chunk logChunk];
		lastChunkType = [chunk typeOfChunk];
		if (lastChunkType == DateAndTimeChunkType) {
			date = [chunk dateValue];
			relative_sequenceno = 0;
			cumulativeDistance = 0;
		} else if (lastChunkType == AutomemWorkoutChunkType) {
			SCWorkoutDataBlock *db = [[SCWorkoutDataBlock alloc] init];
			[db setDate:date];
			[db setRelativeSequenceno:relative_sequenceno];
			[db setSequenceno:sequenceno];
			cumulativeDistance += [chunk getDistance];
			[db setCumulativeDistance:cumulativeDistance];
			[db setWorkoutData:chunk];
			if (automem_area == YES) [db setMemType:AutomemType]; else [db setMemType:WorkoutmemType];

			sequenceno++;
			relative_sequenceno++;
			[destinationArray addObject:db];
			NSLog(@"memoryblock has %i objects", [destinationArray count]);
			
			[db release];
		} else {
		}
		[chunk release];
		
		i++;
	} while (i < i_threshold && lastChunkType != NullChunkType);
	return (NSArray *) destinationArray;
}

-(void) parse {
	[self setAutomem:[self parseWorkoutMemoryBlock:YES]];
	[self setWorkoutmem:[self parseWorkoutMemoryBlock:NO]];
	
}

-(NSData *) automemChunkByNum:(int) num {
	char buffer[1024];

	if (num < 0) return nil;
	if (num > 1499) return nil;
	NSRange range;
	range.length = 16;
	range.location = 0x0 + (16 * num);
	[data getBytes:&buffer range:range];
	return [NSData dataWithBytes:buffer length:16];
}

-(NSData *) workoutmemChunkByNum:(int) num {
	char buffer[1024];
	
	if (num < 0) return nil;
	if (num > 509) return nil;
	NSRange range;
	range.length = 16;
	range.location = 0x5de0 + (16 * num);
	[data getBytes:&buffer range:range];
	return [NSData dataWithBytes:buffer length:16];
}


+(BOOL) isValidEprom1:(NSData *)data {
	char buffer[1024];
	if ([data length] != 32776) {
		NSLog(@"isValidEprom1: FAIL: length != 32778");
		return NO;
	}
	/* from NK's documentation:
	 0x31, 0x41, 0x59, 0x26 are stored in bytes 5DD0 to 5DD3 to indicate good data
	 is in the eeprom, so that it will not be cleared on cold start, and data can be
	 recovered.
	 */
	NSRange range;
	range.length = 4;
	range.location = 0x5dd0;
	[data getBytes:&buffer range:range];
	if (buffer[0] == 0x31 && buffer[1] == 0x41 && buffer[2] == 0x59 && buffer[3] == 0x26) {
		return YES;
	}
	return NO;
}
@end
